home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / asm-frv / checksum.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  4.6 KB  |  181 lines

  1. /* checksum.h: FRV checksumming
  2.  *
  3.  * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
  4.  * Written by David Howells (dhowells@redhat.com)
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License
  8.  * as published by the Free Software Foundation; either version
  9.  * 2 of the License, or (at your option) any later version.
  10.  */
  11.  
  12. #ifndef _ASM_CHECKSUM_H
  13. #define _ASM_CHECKSUM_H
  14.  
  15. #include <linux/in6.h>
  16.  
  17. /*
  18.  * computes the checksum of a memory block at buff, length len,
  19.  * and adds in "sum" (32-bit)
  20.  *
  21.  * returns a 32-bit number suitable for feeding into itself
  22.  * or csum_tcpudp_magic
  23.  *
  24.  * this function must be called with even lengths, except
  25.  * for the last fragment, which may be odd
  26.  *
  27.  * it's best to have buff aligned on a 32-bit boundary
  28.  */
  29. __wsum csum_partial(const void *buff, int len, __wsum sum);
  30.  
  31. /*
  32.  * the same as csum_partial, but copies from src while it
  33.  * checksums
  34.  *
  35.  * here even more important to align src and dst on a 32-bit (or even
  36.  * better 64-bit) boundary
  37.  */
  38. __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum);
  39.  
  40. /*
  41.  * the same as csum_partial_copy, but copies from user space.
  42.  *
  43.  * here even more important to align src and dst on a 32-bit (or even
  44.  * better 64-bit) boundary
  45.  */
  46. extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
  47.                         int len, __wsum sum, int *csum_err);
  48.  
  49. /*
  50.  *    This is a version of ip_compute_csum() optimized for IP headers,
  51.  *    which always checksum on 4 octet boundaries.
  52.  *
  53.  */
  54. static inline
  55. __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
  56. {
  57.     unsigned int tmp, inc, sum = 0;
  58.  
  59.     asm("    addcc        gr0,gr0,gr0,icc0\n" /* clear icc0.C */
  60.         "    subi        %1,#4,%1    \n"
  61.         "0:                    \n"
  62.         "    ldu.p        @(%1,%3),%4    \n"
  63.         "    subicc        %2,#1,%2,icc1    \n"
  64.         "    addxcc.p    %4,%0,%0,icc0    \n"
  65.         "    bhi        icc1,#2,0b    \n"
  66.  
  67.         /* fold the 33-bit result into 16-bits */
  68.         "    addxcc        gr0,%0,%0,icc0    \n"
  69.         "    srli        %0,#16,%1    \n"
  70.         "    sethi        #0,%0        \n"
  71.         "    add        %1,%0,%0    \n"
  72.         "    srli        %0,#16,%1    \n"
  73.         "    add        %1,%0,%0    \n"
  74.  
  75.         : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (inc), "=&r"(tmp)
  76.         : "0" (sum), "1" (iph), "2" (ihl), "3" (4),
  77.         "m"(*(volatile struct { int _[100]; } *)iph)
  78.         : "icc0", "icc1", "memory"
  79.         );
  80.  
  81.     return (__force __sum16)~sum;
  82. }
  83.  
  84. /*
  85.  *    Fold a partial checksum
  86.  */
  87. static inline __sum16 csum_fold(__wsum sum)
  88. {
  89.     unsigned int tmp;
  90.  
  91.     asm("    srli        %0,#16,%1    \n"
  92.         "    sethi        #0,%0        \n"
  93.         "    add        %1,%0,%0    \n"
  94.         "    srli        %0,#16,%1    \n"
  95.         "    add        %1,%0,%0    \n"
  96.         : "=r"(sum), "=&r"(tmp)
  97.         : "0"(sum)
  98.         );
  99.  
  100.     return (__force __sum16)~sum;
  101. }
  102.  
  103. /*
  104.  * computes the checksum of the TCP/UDP pseudo-header
  105.  * returns a 16-bit checksum, already complemented
  106.  */
  107. static inline __wsum
  108. csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
  109.           unsigned short proto, __wsum sum)
  110. {
  111.     asm("    addcc        %1,%0,%0,icc0    \n"
  112.         "    addxcc        %2,%0,%0,icc0    \n"
  113.         "    addxcc        %3,%0,%0,icc0    \n"
  114.         "    addxcc        gr0,%0,%0,icc0    \n"
  115.         : "=r" (sum)
  116.         : "r" (daddr), "r" (saddr), "r" (len + proto), "0"(sum)
  117.         : "icc0"
  118.         );
  119.     return sum;
  120. }
  121.  
  122. static inline __sum16
  123. csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
  124.           unsigned short proto, __wsum sum)
  125. {
  126.     return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
  127. }
  128.  
  129. /*
  130.  * this routine is used for miscellaneous IP-like checksums, mainly
  131.  * in icmp.c
  132.  */
  133. extern __sum16 ip_compute_csum(const void *buff, int len);
  134.  
  135. #define _HAVE_ARCH_IPV6_CSUM
  136. static inline __sum16
  137. csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
  138.         __u32 len, unsigned short proto, __wsum sum)
  139. {
  140.     unsigned long tmp, tmp2;
  141.  
  142.     asm("    addcc        %2,%0,%0,icc0    \n"
  143.  
  144.         /* add up the source addr */
  145.         "    ldi        @(%3,0),%1    \n"
  146.         "    addxcc        %1,%0,%0,icc0    \n"
  147.         "    ldi        @(%3,4),%2    \n"
  148.         "    addxcc        %2,%0,%0,icc0    \n"
  149.         "    ldi        @(%3,8),%1    \n"
  150.         "    addxcc        %1,%0,%0,icc0    \n"
  151.         "    ldi        @(%3,12),%2    \n"
  152.         "    addxcc        %2,%0,%0,icc0    \n"
  153.  
  154.         /* add up the dest addr */
  155.         "    ldi        @(%4,0),%1    \n"
  156.         "    addxcc        %1,%0,%0,icc0    \n"
  157.         "    ldi        @(%4,4),%2    \n"
  158.         "    addxcc        %2,%0,%0,icc0    \n"
  159.         "    ldi        @(%4,8),%1    \n"
  160.         "    addxcc        %1,%0,%0,icc0    \n"
  161.         "    ldi        @(%4,12),%2    \n"
  162.         "    addxcc        %2,%0,%0,icc0    \n"
  163.  
  164.         /* fold the 33-bit result into 16-bits */
  165.         "    addxcc        gr0,%0,%0,icc0    \n"
  166.         "    srli        %0,#16,%1    \n"
  167.         "    sethi        #0,%0        \n"
  168.         "    add        %1,%0,%0    \n"
  169.         "    srli        %0,#16,%1    \n"
  170.         "    add        %1,%0,%0    \n"
  171.  
  172.         : "=r" (sum), "=&r" (tmp), "=r" (tmp2)
  173.         : "r" (saddr), "r" (daddr), "0" (sum), "2" (len + proto)
  174.         : "icc0"
  175.         );
  176.  
  177.     return (__force __sum16)~sum;
  178. }
  179.  
  180. #endif /* _ASM_CHECKSUM_H */
  181.